package com.render3d;

import java.awt.Graphics2D;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.math3d.TexturePolygon3d;
import com.math3d.Transform3d;
import com.math3d.ViewWindow;
import com.render3d.texture.ShadedSurface;
import com.render3d.texture.Texture;

/**
    The ShadedSurfacePolygonRenderer is a PolygonRenderer that
    renders polygons with ShadedSurfaces. It keeps track of
    built surfaces, and clears any surfaces that weren't used
    in the last rendered frame to save memory.
*/
public class ShadedSurfacePolygonRenderer
    extends FastTexturePolygonRender
{

    @SuppressWarnings("unchecked")
	private List builtSurfaces = new LinkedList();

    public ShadedSurfacePolygonRenderer(Transform3d camera,
        ViewWindow viewWindow)
    {
        this(camera, viewWindow, true);
    }

    public ShadedSurfacePolygonRenderer(Transform3d camera,
        ViewWindow viewWindow, boolean eraseView)
    {
        super(viewWindow, camera, eraseView);
    }

    @SuppressWarnings("unchecked")
	public void endFrame(Graphics2D g) {
        super.endFrame(g);

        // clear all built surfaces that weren't used this frame.
        Iterator i = builtSurfaces.iterator();
        while (i.hasNext()) {
            ShadedSurface surface = (ShadedSurface)i.next();
            if (surface.isDirty()) {
                surface.clearSurface();
                i.remove();
            }
            else {
                surface.setDirty(true);
            }
        }
    }

    @Override
    protected void drawCurrenPolygon(Graphics2D g2d) {
    	// TODO Auto-generated method stub
    	buildSurface();
    	super.drawCurrenPolygon(g2d);
    }


    /**
        Builds the surface of the polygon if it has a
        ShadedSurface that is cleared.
    */
    @SuppressWarnings("unchecked")
	protected void buildSurface() {
        // build surface, if needed
        if (sourcePolygon3d instanceof TexturePolygon3d) {
            Texture texture =
                ((TexturePolygon3d)sourcePolygon3d).getTexture();
            if (texture instanceof ShadedSurface) {
                ShadedSurface surface =
                    (ShadedSurface)texture;
                if (surface.isCleared()) {
                    surface.buildSurface();
                    builtSurfaces.add(surface);
                }
                surface.setDirty(false);
            }
        }
    }

}
